package Underworld_Survival;

import java.io.Serializable;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

//货币类型
enum CurrencyType {
    GOLD("金币\uD83D\uDCB0"),   // 金币
    DIAMOND("钻石\uD83D\uDC8E"); // 钻石
    private final String description;
    CurrencyType(String description){
        this.description=description;
    }
    public String getDescription(){
        return description;
    }
}


public class Bag implements Serializable {
    private List<Food> food;//食物列表
    private List<Scroll> scroll;//卷轴列表
    private List<OtherItem> otherItem;//其他道具列表
    private List<Weapon> weapon;//武器列表
    private List<Armor> armor;//防具列表
    private List<Shoe> shoe;//鞋子列表
    private int gold;//金币
    private int diamond;//钻石

    public Bag() {
        food=new ArrayList<>();scroll=new ArrayList<>();
        weapon=new ArrayList<>();armor=new ArrayList<>();
        shoe=new ArrayList<>();otherItem=new ArrayList<>();
        gold=0;diamond=0;
    }
    public Bag(List<Food> food, List<Scroll> scroll, List<OtherItem> otherItem,
               List<Weapon> weapon, List<Armor> armor, List<Shoe> shoe, int gold, int diamond) {
        this.food = food;this.scroll = scroll;
        this.otherItem = otherItem;this.weapon = weapon;
        this.armor = armor;this.shoe = shoe;
        this.gold = gold;this.diamond = diamond;
    }

    public void showBagHorizontally(){//展示背包所有物品
        System.out.println("\n背包："+"\n金币\uD83D\uDCB0："+getGold()+"\t钻石\uD83D\uDC8E："+getDiamond());
        if(food.isEmpty()&& scroll.isEmpty()&&otherItem.isEmpty()&& weapon.isEmpty()&& armor.isEmpty()&&shoe.isEmpty()){
            System.out.println("背包一无所有...");
        }
        this.showFoodHorizontally();
        this.showScrollHorizontally();
        this.showOtherItemHorizontally();
        this.showWeaponHorizontally();
        this.showArmorHorizontally();
        this.showShoeHorizontally();
    }
    public List<? extends Item > showBagVertically(){

        List<? extends Item> allItem = getAllItem();

        Map<String, List<? extends Item >> itemGroup = safeGrouping((List<? extends Item>) allItem);
        List<? extends Item > distinctItemList =getAllItem().stream()
                .collect(Collectors.collectingAndThen(
                        Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(Item::getName))),
                        ArrayList::new
                ));
        if(distinctItemList.isEmpty()){
            System.out.println("你没有任何物品！");
        }else{
            int count = 1;
            for (Item item : distinctItemList) {
                String itemName = item.getName();
                List<? extends Item > group = itemGroup.get(itemName);
                int quantity = group.size();
                int price = group.get(0).getPriceOfSelling();
                System.out.println(count + "." + itemName + "*" + quantity + '\t' + " （售价：" + price + "）");
                count++;
            }
        }
        return distinctItemList;
    }
    public void showBagDetailed(){
        Map<String, List<Item>> itemGroup = getAllItem().stream()
                .collect(Collectors.groupingBy(Item::getName));
        List<Item> distinctItemList =getAllItem().stream()
                .collect(Collectors.collectingAndThen(
                        Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(Item::getName))),
                        ArrayList::new
                ));
        if(distinctItemList.isEmpty()){
            System.out.println("你没有任何物品！");
        }else{
            int count=1;
            for (Item item : distinctItemList) {
                String itemName = item.getName();
                List<Item> group = itemGroup.get(itemName);
                System.out.printf("%d.%s*%d\n效果：%s\n售价：%d\n介绍：%s\n",count,itemName,group.size(),
                        group.get(0).getItemEffect(),group.get(0).getPriceOfSelling(),
                        group.get(0).getIntroduction());
                count++;
            }
        }
    }
    public void showFoodHorizontally(){//展示食物
        if(!this.getFood().isEmpty()){
            System.out.print("食物\uD83C\uDF56：");
            Map<String,Long> nameCountMap=this.getFood().stream().collect(Collectors.groupingBy(Item::getName,Collectors.counting()));
            nameCountMap.forEach((name, count) -> System.out.print(name + "*" + count+"    "));
            System.out.println();
        }
    }
    public List<Food> showFoodVertically(){
        Map<String, List<Food>> itemGroup = getFood().stream()
                .collect(Collectors.groupingBy(Food::getName));
        List<Food> distinctItemList =getFood().stream()
                .collect(Collectors.collectingAndThen(
                        Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(Food::getName))),
                        ArrayList::new
                ));
        if(!distinctItemList.isEmpty()){
            int count = 1;
            for (Food item : distinctItemList) {
                String itemName = item.getName();
                List<Food> group = itemGroup.get(itemName);
                int quantity = group.size();
                int price = group.get(0).getPriceOfSelling();
                System.out.println(count + "." + itemName + "*" + quantity+'\t'+"("+group.get(0).getItemEffect()+")");
                count++;
            }
        }else{
            System.out.println("你没有任何食物！");
        }
        return distinctItemList;
    }
    public void showScrollHorizontally(){//展示卷轴
        if(!this.getScroll().isEmpty()){
            System.out.print("卷轴\uD83D\uDCDC：");
            Map<String,Long> nameCountMap=this.getScroll().stream().collect(Collectors.groupingBy(Item::getName,Collectors.counting()));
            nameCountMap.forEach((name, count) -> System.out.print(name + "*" + count+"    "));
            System.out.println();
        }
    }
    public List<Scroll> showScrollVertically(){
        Map<String, List<Scroll>> itemGroup = getScroll().stream()
                .collect(Collectors.groupingBy(Item::getName));
        List<Scroll> distinctItemList =getScroll().stream()
                .collect(Collectors.collectingAndThen(
                        Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(Item::getName))),
                        ArrayList::new
                ));
        if(distinctItemList.isEmpty()){
            System.out.println("你没有任何卷轴！");
        }else{
            int count = 1;
            for (Scroll item : distinctItemList) {
                String itemName = item.getName();
                List<Scroll> group = itemGroup.get(itemName);
                int quantity = group.size();
                int price = group.get(0).getPriceOfSelling();
                System.out.println(count + "." + itemName + "*" + quantity+'\t'+"("+group.get(0).getItemEffect()+")");
                count++;
            }
        }
        return distinctItemList;
    }
    public void showOtherItemHorizontally(){//展示其他道具
        if(!this.getOtherItem().isEmpty()){
            System.out.print("道具\uD83D\uDD18：");
            Map<String,Long> nameCountMap=this.getOtherItem().stream().collect(Collectors.groupingBy(Item::getName,Collectors.counting()));
            nameCountMap.forEach((name, count) -> System.out.print(name + "*" + count+"    "));
            System.out.println();
        }
    }
    public List<OtherItem> showOtherItemVertically(){
        Map<String, List<OtherItem>> itemGroup = getOtherItem().stream()
                .collect(Collectors.groupingBy(Item::getName));
        List<OtherItem> distinctItemList =getOtherItem().stream()
                .collect(Collectors.collectingAndThen(
                        Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(Item::getName))),
                        ArrayList::new
                ));
        if(distinctItemList.isEmpty()){
            System.out.println("你没有任何道具！");
        }else{
            int count = 1;
            for (Item item : distinctItemList) {
                String itemName = item.getName();
                List<OtherItem> group = itemGroup.get(itemName);
                int quantity = group.size();
                int price = group.get(0).getPriceOfSelling();
                System.out.println(count + "." + itemName + "*" + quantity+'\t'+"("+group.get(0).getItemEffect()+")");
                count++;
            }
        }
        return distinctItemList;
    }
    public void showWeaponHorizontally(){//展示武器
        if(!this.getWeapon().isEmpty()){
            System.out.print("武器🗡️：");
            Map<String,Long> nameCountMap=this.getWeapon().stream().collect(Collectors.groupingBy(Item::getName,Collectors.counting()));
            nameCountMap.forEach((name, count) -> System.out.print(name + "*" + count+"    "));
            System.out.println();
        }
    }
    public List<Weapon > showWeaponVertically(){
        Map<String, List<Weapon>> itemGroup = getWeapon().stream()
                .collect(Collectors.groupingBy(Item::getName));
        List<Weapon> distinctItemList =getWeapon().stream()
                .collect(Collectors.collectingAndThen(
                        Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(Item::getName))),
                        ArrayList::new
                ));
        if(distinctItemList.isEmpty()){
            System.out.println("你没有任何武器！");
        }else{
            int count = 1;
            for (Item item : distinctItemList) {
                String itemName = item.getName();
                List<Weapon> group = itemGroup.get(itemName);
                int quantity = group.size();
                int price = group.get(0).getPriceOfSelling();
                System.out.println(count + "." + itemName + "*" + quantity+'\t'+"("+group.get(0).getItemEffect()+")");
                count++;
            }
        }
        return distinctItemList;
    }
    public void showArmorHorizontally(){//展示防具
        if(!this.getArmor().isEmpty()){
            System.out.print("防具\uD83D\uDEE1\uFE0F：");
            Map<String,Long> nameCountMap=this.getArmor().stream().collect(Collectors.groupingBy(Item::getName,Collectors.counting()));
            nameCountMap.forEach((name, count) -> System.out.print(name + "*" + count+"    "));
            System.out.println();
        }
    }
    public List<Armor > showArmorVertically(){
        Map<String, List<Armor>> itemGroup = getArmor().stream()
                .collect(Collectors.groupingBy(Item::getName));
        List<Armor> distinctItemList =getArmor().stream()
                .collect(Collectors.collectingAndThen(
                        Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(Item::getName))),
                        ArrayList::new
                ));
        if(distinctItemList.isEmpty()){
            System.out.println("你没有任何防具！");
        }else{
            int count = 1;
            for (Item item : distinctItemList) {
                String itemName = item.getName();
                List<Armor> group = itemGroup.get(itemName);
                int quantity = group.size();
                int price = group.get(0).getPriceOfSelling();
                System.out.println(count + "." + itemName + "*" + quantity+'\t'+"("+group.get(0).getItemEffect()+")");
                count++;
            }
        }
        return distinctItemList;
    }
    public void showShoeHorizontally(){//展示鞋子
        if(!this.getShoe().isEmpty()){
            System.out.print("鞋子👟：");
            Map<String,Long> nameCountMap=this.getShoe().stream().collect(Collectors.groupingBy(Item::getName,Collectors.counting()));
            nameCountMap.forEach((name, count) -> System.out.print(name + "*" + count+"    "));
            System.out.println();
        }
    }
    public List<Shoe > showShoeVertically(){
        Map<String, List<Shoe>> itemGroup = getShoe().stream()
                .collect(Collectors.groupingBy(Item::getName));
        List<Shoe> distinctItemList =getShoe().stream()
                .collect(Collectors.collectingAndThen(
                        Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(Item::getName))),
                        ArrayList::new
                ));
        if(distinctItemList.isEmpty()){
            System.out.println("你没有任何鞋子！");
        }else{
            int count = 1;
            for (Item item : distinctItemList) {
                String itemName = item.getName();
                List<Shoe> group = itemGroup.get(itemName);
                int quantity = group.size();
                int price = group.get(0).getPriceOfSelling();
                System.out.println(count + "." + itemName + "*" + quantity+'\t'+"("+group.get(0).getItemEffect()+")");
                count++;
            }
        }
        return distinctItemList;
    }


    @SuppressWarnings("unchecked")
    private static <T extends Item> Map<String, List<? extends Item>> safeGrouping(List<T> item) {
        Map<String, List<T>> tempMap = item.stream()
                .collect(Collectors.groupingBy(Item::getName));
        Map<String, List<? extends Item>> resultMap = new HashMap<>();
        tempMap.forEach((key, value) -> resultMap.put(key, (List<? extends Item>) value));
        return resultMap;
    }
    public List<? extends Item > getAllItem(){//获取所有列表
        return Stream.of(food, weapon, armor, shoe, scroll, otherItem)
                .flatMap(List::stream)
                .collect(Collectors.toList());
    }

    // 获取所有背包物品的合并视图（用于存档）
    public Map<String, Integer> getConsolidatedBag() {
        Map<String, Integer> inventory = new HashMap<>();

        Stream.of(food, scroll,otherItem, weapon, armor, shoe)
                .flatMap(Collection::stream)
                .forEach(item -> {
                    String typeId = item.getItemId();
                    inventory.put(typeId, inventory.getOrDefault(typeId, 0) + 1);
                });
        return inventory;
    }

    public List<Food> getFood() {return food;}
    public void setFood(List<Food> food) {this.food = food;}
    public List<Scroll> getScroll() {return scroll;}
    public void setScroll(List<Scroll> scroll) {this.scroll = scroll;}
    public List<OtherItem> getOtherItem() {return otherItem;}
    public void setOtherItem(List<OtherItem> otherItem) {this.otherItem = otherItem;}
    public List<Weapon> getWeapon() {return weapon;}
    public void setWeapon(List<Weapon> weapon) {this.weapon = weapon;}
    public List<Armor> getArmor() {return armor;}
    public void setArmor(List<Armor> armor) {this.armor = armor;}
    public List<Shoe> getShoe() {return shoe;}
    public void setShoe(List<Shoe> shoe) {this.shoe = shoe;}
    public int getGold() {return gold;}
    public void setGold(int gold) {this.gold = gold;}
    public int getDiamond() {return diamond;}
    public void setDiamond(int diamond) {this.diamond = diamond;}


}
